package models

import (
	"errors"
	"fmt"
	"sync"
	"time"
)

// VenueStateManager 场地状态管理器
type VenueStateManager struct {
	states map[int64]*VenueState
	mutex  sync.RWMutex
}

// VenueState 场地状态
type VenueState struct {
	VenueID       int64                  `json:"venue_id"`
	CurrentState  VenueStateType         `json:"current_state"`
	PreviousState VenueStateType         `json:"previous_state"`
	StateHistory  []StateChange          `json:"state_history"`
	Lock          sync.RWMutex           `json:"-"`
	LastUpdate    int64                  `json:"last_update"`
	Metadata      map[string]interface{} `json:"metadata"`
}

// VenueStateType 场地状态类型
type VenueStateType int

const (
	StateIdle VenueStateType = iota + 1
	StateReserved
	StateInUse
	StatePendingCleaning
	StateCleaning
	StateMaintenance
	StateOutOfService
)

// String 返回状态字符串表示
func (vst VenueStateType) String() string {
	switch vst {
	case StateIdle:
		return "空闲中"
	case StateReserved:
		return "已预约"
	case StateInUse:
		return "使用中"
	case StatePendingCleaning:
		return "待保洁"
	case StateCleaning:
		return "保洁中"
	case StateMaintenance:
		return "维护中"
	case StateOutOfService:
		return "暂停服务"
	default:
		return "未知状态"
	}
}

// StateChange 状态变更记录
type StateChange struct {
	FromState VenueStateType `json:"from_state"`
	ToState   VenueStateType `json:"to_state"`
	Reason    string         `json:"reason"`
	Timestamp int64          `json:"timestamp"`
	UserID    int64          `json:"user_id"`
	OrderID   int64          `json:"order_id"`
}

// StateTransition 状态转换规则
type StateTransition struct {
	FromState VenueStateType
	ToState   VenueStateType
	Allowed   bool
	Condition func(*VenueState, map[string]interface{}) bool
}

// BookingConflict 预约冲突信息
type BookingConflict struct {
	Conflicting bool
	Reason      string
	OverlapTime int64
	Alternative []AlternativeSlot
}

// AlternativeSlot 替代时段
type AlternativeSlot struct {
	StartTime int64   `json:"start_time"`
	EndTime   int64   `json:"end_time"`
	Price     float64 `json:"price"`
}

// NewVenueStateManager 创建新的场地状态管理器
func NewVenueStateManager() *VenueStateManager {
	return &VenueStateManager{
		states: make(map[int64]*VenueState),
	}
}

// InitializeVenue 初始化场地状态
func (vsm *VenueStateManager) InitializeVenue(venueID int64) {
	vsm.mutex.Lock()
	defer vsm.mutex.Unlock()

	state := &VenueState{
		VenueID:      venueID,
		CurrentState: StateIdle,
		StateHistory: []StateChange{},
		LastUpdate:   time.Now().Unix(),
		Metadata:     make(map[string]interface{}),
	}

	vsm.states[venueID] = state
}

// GetState 获取场地当前状态
func (vsm *VenueStateManager) GetState(venueID int64) (*VenueState, error) {
	vsm.mutex.RLock()
	defer vsm.mutex.RUnlock()

	state, exists := vsm.states[venueID]
	if !exists {
		return nil, errors.New("场地不存在")
	}

	return state, nil
}

// ChangeState 变更场地状态
func (vsm *VenueStateManager) ChangeState(venueID int64, newState VenueStateType, reason string, userID int64, orderID int64) error {
	vsm.mutex.Lock()
	defer vsm.mutex.Unlock()

	state, exists := vsm.states[venueID]
	if !exists {
		return errors.New("场地不存在")
	}

	state.Lock.Lock()
	defer state.Lock.Unlock()

	// 验证状态转换
	if !vsm.isValidTransition(state.CurrentState, newState) {
		return fmt.Errorf("无效的状态转换: %s → %s", state.CurrentState.String(), newState.String())
	}

	// 记录状态变更
	change := StateChange{
		FromState: state.CurrentState,
		ToState:   newState,
		Reason:    reason,
		Timestamp: time.Now().Unix(),
		UserID:    userID,
		OrderID:   orderID,
	}

	state.StateHistory = append(state.StateHistory, change)
	state.PreviousState = state.CurrentState
	state.CurrentState = newState
	state.LastUpdate = time.Now().Unix()

	return nil
}

// isValidTransition 验证状态转换是否有效
func (vsm *VenueStateManager) isValidTransition(from, to VenueStateType) bool {
	transitions := map[VenueStateType][]VenueStateType{
		StateIdle:            {StateReserved, StateMaintenance, StateOutOfService},
		StateReserved:        {StateInUse, StateIdle, StateOutOfService},
		StateInUse:           {StatePendingCleaning, StateOutOfService},
		StatePendingCleaning: {StateCleaning, StateOutOfService},
		StateCleaning:        {StateIdle, StateMaintenance, StateOutOfService},
		StateMaintenance:     {StateIdle, StateOutOfService},
		StateOutOfService:    {StateIdle, StateMaintenance},
	}

	allowedTransitions, exists := transitions[from]
	if !exists {
		return false
	}

	for _, allowed := range allowedTransitions {
		if allowed == to {
			return true
		}
	}

	return false
}

// CheckBookingAvailability 检查预约可用性
func (vsm *VenueStateManager) CheckBookingAvailability(venueID int64, startTime, endTime int64) (*BookingConflict, error) {
	state, err := vsm.GetState(venueID)
	if err != nil {
		return nil, err
	}

	// 检查当前状态是否允许预约
	if state.CurrentState != StateIdle {
		return &BookingConflict{
			Conflicting: true,
			Reason:      fmt.Sprintf("场地当前状态为：%s", state.CurrentState.String()),
			OverlapTime: 0,
			Alternative: []AlternativeSlot{},
		}, nil
	}

	// 检查是否有待处理的状态变更
	if vsm.hasPendingStateChange(venueID, startTime, endTime) {
		return &BookingConflict{
			Conflicting: true,
			Reason:      "场地在该时段有预定的状态变更",
			OverlapTime: 0,
			Alternative: []AlternativeSlot{},
		}, nil
	}

	return &BookingConflict{
		Conflicting: false,
		Reason:      "场地可用",
		OverlapTime: 0,
		Alternative: []AlternativeSlot{},
	}, nil
}

// hasPendingStateChange 检查是否有待处理的状态变更
func (vsm *VenueStateManager) hasPendingStateChange(venueID int64, startTime, endTime int64) bool {
	// 这里应该查询数据库检查是否有预约订单
	// 简化处理：返回false
	return false
}

// FindAlternativeSlots 查找替代时段
func (vsm *VenueStateManager) FindAlternativeSlots(venueID int64, startTime, endTime int64, duration int) []AlternativeSlot {
	// 这里应该查询数据库查找可用时段
	// 简化处理：返回示例时段
	alternatives := []AlternativeSlot{
		{
			StartTime: startTime + 3600, // 延后1小时
			EndTime:   startTime + 3600 + int64(duration*3600),
			Price:     100.0,
		},
		{
			StartTime: startTime - 3600, // 提前1小时
			EndTime:   startTime - 3600 + int64(duration*3600),
			Price:     90.0,
		},
	}

	return alternatives
}

// ReserveVenue 预约场地
func (vsm *VenueStateManager) ReserveVenue(venueID int64, startTime, endTime int64, userID int64, orderID int64) error {
	_, err := vsm.GetState(venueID)
	if err != nil {
		return err
	}

	// 检查预约可用性
	conflict, err := vsm.CheckBookingAvailability(venueID, startTime, endTime)
	if err != nil {
		return err
	}

	if conflict.Conflicting {
		return errors.New(conflict.Reason)
	}

	// 变更状态为已预约
	return vsm.ChangeState(venueID, StateReserved, "用户预约", userID, orderID)
}

// StartUsage 开始使用
func (vsm *VenueStateManager) StartUsage(venueID int64, userID int64, orderID int64) error {
	return vsm.ChangeState(venueID, StateInUse, "用户开始使用", userID, orderID)
}

// EndUsage 结束使用
func (vsm *VenueStateManager) EndUsage(venueID int64, userID int64, orderID int64) error {
	return vsm.ChangeState(venueID, StatePendingCleaning, "使用结束，待保洁", userID, orderID)
}

// StartCleaning 开始保洁
func (vsm *VenueStateManager) StartCleaning(venueID int64, cleanerID int64) error {
	return vsm.ChangeState(venueID, StateCleaning, "开始保洁", cleanerID, 0)
}

// CompleteCleaning 完成保洁
func (vsm *VenueStateManager) CompleteCleaning(venueID int64, cleanerID int64) error {
	return vsm.ChangeState(venueID, StateIdle, "保洁完成", cleanerID, 0)
}

// StartMaintenance 开始维护
func (vsm *VenueStateManager) StartMaintenance(venueID int64, maintainerID int64) error {
	return vsm.ChangeState(venueID, StateMaintenance, "开始维护", maintainerID, 0)
}

// CompleteMaintenance 完成维护
func (vsm *VenueStateManager) CompleteMaintenance(venueID int64, maintainerID int64) error {
	return vsm.ChangeState(venueID, StateIdle, "维护完成", maintainerID, 0)
}

// SetOutOfService 设置暂停服务
func (vsm *VenueStateManager) SetOutOfService(venueID int64, reason string, operatorID int64) error {
	return vsm.ChangeState(venueID, StateOutOfService, reason, operatorID, 0)
}

// GetStateHistory 获取状态历史
func (vsm *VenueStateManager) GetStateHistory(venueID int64) ([]StateChange, error) {
	state, err := vsm.GetState(venueID)
	if err != nil {
		return nil, err
	}

	return state.StateHistory, nil
}

// GetVenueUtilization 获取场地利用率
func (vsm *VenueStateManager) GetVenueUtilization(venueID int64, startTime, endTime int64) (float64, error) {
	_, err := vsm.GetState(venueID)
	if err != nil {
		return 0, err
	}

	// 这里应该查询数据库计算实际利用率
	// 简化处理：返回示例值
	utilization := 0.75 // 75% 利用率
	return utilization, nil
}

// GetBatchStates 批量获取场地状态
func (vsm *VenueStateManager) GetBatchStates(venueIDs []int64) (map[int64]*VenueState, error) {
	vsm.mutex.RLock()
	defer vsm.mutex.RUnlock()

	result := make(map[int64]*VenueState)
	for _, venueID := range venueIDs {
		if state, exists := vsm.states[venueID]; exists {
			result[venueID] = state
		}
	}

	return result, nil
}

// ProcessExpiredReservations 处理过期预约
func (vsm *VenueStateManager) ProcessExpiredReservations() error {
	vsm.mutex.Lock()
	defer vsm.mutex.Unlock()

	currentTime := time.Now().Unix()

	for venueID, state := range vsm.states {
		if state.CurrentState == StateReserved {
			// 检查预约是否过期
			if vsm.isReservationExpired(venueID, currentTime) {
				vsm.ChangeState(venueID, StateIdle, "预约过期自动释放", 0, 0)
			}
		}
	}

	return nil
}

// isReservationExpired 检查预约是否过期
func (vsm *VenueStateManager) isReservationExpired(venueID int64, currentTime int64) bool {
	// 这里应该查询数据库检查预约过期时间
	// 简化处理：返回false
	return false
}

// GetVenueStatusSummary 获取场地状态摘要
func (vsm *VenueStateManager) GetVenueStatusSummary(storeID int64) (map[VenueStateType]int, error) {
	vsm.mutex.RLock()
	defer vsm.mutex.RUnlock()

	summary := make(map[VenueStateType]int)

	for _, state := range vsm.states {
		summary[state.CurrentState]++
	}

	return summary, nil
}

// ProcessCleaningSchedule 处理保洁调度
func (vsm *VenueStateManager) ProcessCleaningSchedule() error {
	vsm.mutex.Lock()
	defer vsm.mutex.Unlock()

	currentTime := time.Now().Unix()

	for venueID, state := range vsm.states {
		if state.CurrentState == StatePendingCleaning {
			// 检查是否可以开始保洁
			if vsm.canStartCleaning(venueID, currentTime) {
				vsm.ChangeState(venueID, StateCleaning, "自动调度保洁", 0, 0)
			}
		}
	}

	return nil
}

// canStartCleaning 检查是否可以开始保洁
func (vsm *VenueStateManager) canStartCleaning(venueID int64, currentTime int64) bool {
	// 这里应该检查保洁人员可用性和调度规则
	// 简化处理：返回true
	return true
}

// GetRealtimeStatus 获取实时状态
func (vsm *VenueStateManager) GetRealtimeStatus(venueID int64) (*RealtimeVenueStatus, error) {
	state, err := vsm.GetState(venueID)
	if err != nil {
		return nil, err
	}

	status := &RealtimeVenueStatus{
		VenueID:      venueID,
		CurrentState: state.CurrentState,
		StateName:    state.CurrentState.String(),
		LastUpdate:   state.LastUpdate,
		NextState:    vsm.predictNextState(state),
		Occupancy:    0, // 这里应该查询实际占用率
	}

	return status, nil
}

// RealtimeVenueStatus 实时场地状态
type RealtimeVenueStatus struct {
	VenueID      int64          `json:"venue_id"`
	CurrentState VenueStateType `json:"current_state"`
	StateName    string         `json:"state_name"`
	LastUpdate   int64          `json:"last_update"`
	NextState    VenueStateType `json:"next_state"`
	Occupancy    float64        `json:"occupancy"`
}

// predictNextState 预测下一个状态
func (vsm *VenueStateManager) predictNextState(state *VenueState) VenueStateType {
	switch state.CurrentState {
	case StateReserved:
		return StateInUse
	case StateInUse:
		return StatePendingCleaning
	case StateCleaning:
		return StateIdle
	case StateMaintenance:
		return StateIdle
	default:
		return state.CurrentState
	}
}

// HandleEmergency 处理紧急情况
func (vsm *VenueStateManager) HandleEmergency(venueID int64, emergencyType string, operatorID int64) error {
	_, err := vsm.GetState(venueID)
	if err != nil {
		return err
	}

	// 根据紧急情况处理
	switch emergencyType {
	case "equipment_failure":
		return vsm.ChangeState(venueID, StateOutOfService, "设备故障紧急停用", operatorID, 0)
	case "cleaning_urgent":
		return vsm.ChangeState(venueID, StatePendingCleaning, "紧急保洁需求", operatorID, 0)
	case "maintenance_urgent":
		return vsm.ChangeState(venueID, StateMaintenance, "紧急维护需求", operatorID, 0)
	default:
		return errors.New("未知的紧急情况类型")
	}
}

// GetStateTransitionMatrix 获取状态转换矩阵
func (vsm *VenueStateManager) GetStateTransitionMatrix() map[VenueStateType][]VenueStateType {
	return map[VenueStateType][]VenueStateType{
		StateIdle:            {StateReserved, StateMaintenance, StateOutOfService},
		StateReserved:        {StateInUse, StateIdle, StateOutOfService},
		StateInUse:           {StatePendingCleaning, StateOutOfService},
		StatePendingCleaning: {StateCleaning, StateOutOfService},
		StateCleaning:        {StateIdle, StateMaintenance, StateOutOfService},
		StateMaintenance:     {StateIdle, StateOutOfService},
		StateOutOfService:    {StateIdle, StateMaintenance},
	}
}

// BatchProcessStateChanges 批量处理状态变更
func (vsm *VenueStateManager) BatchProcessStateChanges(changes []StateChangeRequest) []StateChangeResult {
	results := make([]StateChangeResult, len(changes))

	for i, change := range changes {
		err := vsm.ChangeState(change.VenueID, change.NewState, change.Reason, change.UserID, change.OrderID)
		results[i] = StateChangeResult{
			VenueID: change.VenueID,
			Success: err == nil,
			Error:   err,
		}
	}

	return results
}

// StateChangeRequest 状态变更请求
type StateChangeRequest struct {
	VenueID  int64
	NewState VenueStateType
	Reason   string
	UserID   int64
	OrderID  int64
}

// StateChangeResult 状态变更结果
type StateChangeResult struct {
	VenueID int64
	Success bool
	Error   error
}
